/*
 * Copyright (C) 2010 ZXing authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.geor.scan.core.decoding;

import android.content.Intent;
import android.graphics.*;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import com.geor.scan.R;
import com.geor.scan.core.camera.CameraManager;
import com.geor.scan.interfaces.ImageParser;
import com.geor.scan.interfaces.Recognizer;
import com.geor.scan.ui.CaptureActivity;
import org.opencv.utils.Area;
import org.opencv.utils.Util;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

final public class DecodeHandler extends Handler {
    private final CaptureActivity activity;
    public static boolean leftFlag = false;
    public static boolean topFlag = false;
    public static boolean bottomFlag = false;
    public static boolean rightFlag = false;

    DecodeHandler(CaptureActivity activity) {
        this.activity = activity;
    }

    private void init() {
        leftFlag = false;
        topFlag = false;
        bottomFlag = false;
        rightFlag = false;
        index = 0;
    }

    private boolean checkYHK(Bitmap bm) {
        return leftFlag && rightFlag && topFlag && bottomFlag;
    }

    static int index = 0;
    int num = 0;

    @Override
    public void handleMessage(Message message) {
        if (message.what == R.id.decodeCF || message.what == R.id.decodeCR) {
            init();
            decodeSFZ((byte[]) message.obj, message.arg1, message.arg2);
        } else if (message.what == R.id.decodeYHK) {
            decodeYHK((byte[]) message.obj, message.arg1, message.arg2);
        } else if (message.what == R.id.decodeYYZZ) {
            init();
            decodeYYZZ((byte[]) message.obj, message.arg1, message.arg2);
        } else if (message.what == R.id.quit) {
            init();
            Looper.myLooper().quit();
        }
    }

    private void decodeYHK(byte[] data, int width, int height) {
        if (index++ == 0) {
            try {
                TimeUnit.MILLISECONDS.sleep(200);
                sendDecodeFail();
                return;
            } catch (Exception e) {

            }
        }
        Rect rect = CameraManager.get().getFramingRectInPreview();
        Area area1 = new Area(rect.top, rect.left, rect.height(), rect.width());
        if (data == null) {
            sendDecodeFail();
            return;
        }
        // 图片解析
        ImageParser parser = CaptureActivity.getImageParser();
        File file = null;
        try {
            Bitmap bitmap = parser.parser(data, width, height);
            Area area = Util.find(bitmap);
            float scale = (float) area.getWidth() / area.getHeight();
            System.out.println("裁边比例: " + scale + " !@#");
            System.out.println("裁边面积占比: " + (float) area.getArea() / area1.getArea() + "!@#");
            if (scale > 1.5f && scale < 1.64f) {
                num++;
            } else {
                num = 0;
            }
            if (num > 1  && (float) area.getArea() / area1.getArea() > 0.7f) {
                bitmap = Bitmap.createBitmap(bitmap, area1.getX(), area1.getY(), area1.getWidth(), area1.getHeight());
                file = parser.save(bitmap);
                Map<String, String> map = CaptureActivity.getRecognizer().execute(file);
                if (null == map || map.isEmpty() || "9999".equals(map.get("RETCODE"))) {
                    throw new Exception("服务器响应失败!");
                } else {
                    map.put("file.path", file.getAbsolutePath());
                    sendDecodeSuccess(map);
                }
                return;
            }
            throw new Exception("请扫描银行卡图片!");
        } catch (Throwable e) {
            System.out.println(e.getMessage() + "!@#");
            e.printStackTrace();
            if (file != null && file.exists()) {
                file.delete();
            }
            sendDecodeFail();
        }
    }

    private void decodeYYZZ(byte[] data, int width, int height) {
        Rect rect = CameraManager.get().getFramingRectInPreview();
        if (data == null) {
            sendDecodeFail();
            return;
        }
        ImageParser parser = CaptureActivity.getImageParser();
        // 图片解析
        Recognizer recognizer = CaptureActivity.getRecognizer();
        File file = null;
        Map<String, String> map = null;
        try {
            Bitmap bitmap = parser.parser(data, width, height);
            Bitmap bm = adjustPhotoRotation(bitmap, 90);
            bm = Bitmap.createBitmap(bm, rect.left, rect.top, rect.width(), rect.height());
            file = parser.save(bm);
            map = recognizer.execute(file);
            if (null == map || map.isEmpty() || "9999".equals(map.get("RETCODE"))) {
                throw new Exception("识别营业执照失败，请重新拍摄!");
            } else {
                showPhoto(file);
                sendDecodeSuccess(map);
            }
        } catch (Exception e) {
            e.printStackTrace();
            if (file != null && file.exists()) {
                file.delete();
            }
            sendDecodeFail();
        }

    }

    private void showPhoto(File file) {
        //   在手机相册中显示刚拍摄的图片
        Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        // 在系统相册中显示
        Uri contentUri = Uri.fromFile(file);
        mediaScanIntent.setData(contentUri);
        activity.sendBroadcast(mediaScanIntent);
    }

    private void sendDecodeSuccess(Map<String, String> map) {
        Message message = Message.obtain(activity.getHandler(), R.id.decode_succeeded, map);
        message.sendToTarget();
    }

    private void decodeSFZ(byte[] data, int width, int height) {
        if (data == null) {
            sendDecodeFail();
            return;
        }
        // 图片解析
        ImageParser parser = CaptureActivity.getImageParser();
        // 识别
        Recognizer recognizer = CaptureActivity.getRecognizer();
        if (parser == null || recognizer == null) {
            sendDecodeFail();
            return;
        }
        File file = null;
        try {
            Bitmap bm = parser.parser(data, width, height);

            // 判断身份证识别符合标准
            if (!isSfz(bm)) {
                System.out.println("请扫描身份证图片" + "!@#");
                throw new Exception("请扫描身份证图片");
            }
            file = parser.save(bm);

            Map<String, String> map = recognizer.execute(file);
            if (null == map || map.isEmpty() || "9999".equals(map.get("RETCODE"))) {
                throw new Exception("识别失败，请重新拍摄!");
            } else {
                showPhoto(file);
                sendDecodeSuccess(map);
            }
        } catch (Exception e) {
            e.printStackTrace();
            if (file != null) {
                file.delete();
            }
            sendDecodeFail();
        }
    }

    private boolean isSfz(Bitmap bm) {
        if (R.id.decodeCF == CaptureActivity.getType()) {
            return Util.isSfzCf(bm);
        } else if (R.id.decodeCR == CaptureActivity.getType()) {
            return Util.isSfzCr(bm);
        }
        return false;
    }

    private void sendDecodeFail() {
        Message message = Message.obtain(activity.getHandler(), R.id.decode_failed);
        message.sendToTarget();
        System.out.println("send fail !@#");
    }

    Bitmap adjustPhotoRotation(Bitmap bitmap, int orientationDegree) {
        Matrix matrix = new Matrix();
        matrix.setRotate(orientationDegree, (float) bitmap.getWidth() / 2,
                (float) bitmap.getHeight() / 2);
        float targetX, targetY;
        if (orientationDegree == 90) {
            targetX = bitmap.getHeight();
            targetY = 0;
        } else {
            targetX = bitmap.getHeight();
            targetY = bitmap.getWidth();
        }


        final float[] values = new float[9];
        matrix.getValues(values);


        float x1 = values[Matrix.MTRANS_X];
        float y1 = values[Matrix.MTRANS_Y];

        matrix.postTranslate(targetX - x1, targetY - y1);

        Bitmap canvasBitmap = Bitmap.createBitmap(bitmap.getHeight(), bitmap.getWidth(),
                Bitmap.Config.ARGB_8888);


        Paint paint = new Paint();
        Canvas canvas = new Canvas(canvasBitmap);
        canvas.drawBitmap(bitmap, matrix, paint);


        return canvasBitmap;
    }

}
